#include "RTC.hpp"
#include "System.hpp"

struct RTCResource {
    ST::RTC *instance;
    RTC_Register_t *reg;
    System::ClockChannel clock_channel;
    System::InterruptChannel interrupt_channel_wkup;
    System::InterruptChannel interrupt_channel_alarm;
} rtc_resources[] = {
    [0] = {
        .instance = nullptr,
        .reg = (RTC_Register_t*)0x40002800,
        .clock_channel = System::ClockChannel::BKP_SRAM,
        .interrupt_channel_wkup = System::InterruptChannel::RTC_WKUP,
        .interrupt_channel_alarm = System::InterruptChannel::RTC_Alarm,
    },
};

bool ST::RTC::Alarm::setAlarmTime(Time time){
    this->time = time;
    return true;
}

RTC::Time ST::RTC::Alarm::getAlarmTime(void){
    return this->time;
}

class __RTC : public ST::RTC {
public:
    __RTC(int rtc_number);
    virtual ~__RTC();
    virtual bool open(void);
    virtual bool close(void);
    virtual bool setTime(Time time);
    virtual Time getTime(void);

    virtual bool addAlarm(::RTC::Alarm *alarm,EventCallback *alarm_callback);
    virtual bool removeAlarm(::RTC::Alarm *alarm);
private:
    int rtc_number;
};

__RTC::__RTC(int rtc_number){
    this->rtc_number = rtc_number;
}

__RTC::~__RTC(){

}

bool __RTC::open(void){
    return true;
}

bool __RTC::close(void){
    return true;
}

bool __RTC::setTime(Time time){
    return true;
}

RTC::Time __RTC::getTime(void){
    Time time = {
        0,
    };
    return time;
}

bool __RTC::addAlarm(::RTC::Alarm *alarm,EventCallback *alarm_callback){
    return true;
}

bool __RTC::removeAlarm(::RTC::Alarm *alarm){
    return true;
}

ST::RTC *ST::RTC::getInstance(int rtc_number){
    if ( rtc_number >= (sizeof(rtc_resources) / sizeof(RTCResource)) ) return nullptr;
    if ( rtc_resources[rtc_number].instance == nullptr ){
        rtc_resources[rtc_number].instance = new __RTC(rtc_number);
    }
    return rtc_resources[rtc_number].instance;
}

bool ST::RTC::freeInstance(ST::RTC *instance){
    if ( instance == nullptr ) return false;
    for ( int index = 0; index < (sizeof(rtc_resources) / sizeof(RTCResource)); index++ ){
        if ( rtc_resources[index].instance == instance ){
            if ( !rtc_resources[index].instance->close() ) return false;
            delete rtc_resources[index].instance;
            rtc_resources[index].instance = nullptr;
            return true;
        }
    }
    return false;
}